package 逆波兰计算器_后缀;


import java.util.Arrays;
import java.util.List;
import java.util.Stack;

public class 逆波兰计算器_后缀 {
	public static void main(String[] args) {
		//例如: (3+4)*5-6对应的后缀表达式就是3 4 + 5 * 6 -
		//将表达式字符串用空格隔开，便于运算
		//String exp = "3 4 + 5 * 6 -"; //29
		String exp = "3 4 + 5 * 60 -";  //-25
		
		
		//String exp = "34+5*6-"; //不要用，如果是多位数，就分不清了，
		//String[] split = exp.split("");
		
		//将字符串放到List中，更方便 
		String[] split = exp.split(" ");
		List<String> list = Arrays.asList(split);
		
		//创建一个计算方法，将List传入
		int res = cal(list);
		System.out.println(res);
	}

	
	//计算 逆波兰/后缀 表达式
	/**
	 例如: (3+4)*5-6对应的后缀表达式就是3 4 + 5 * 6-， 针对后缀表达式求值步骤如下:
		1. 从左至右扫描，将 3 和 4 压入栈中；
		2. 遇到 + 运算符，弹出3 和 4(栈顶元素和次顶元素)，计算出 3 + 4 ，得 7 ，再将 7 入栈；
		3. 将 5 入栈 ；
		4. 遇到 * 运算符，弹出 5 和 7，计算 7 * 5 = 35，将35 入栈；
		5. 将6 入栈；
		6. 最后 - 运算符，计算35 - 6 = 29，得到最终答案；
		7. 注意：出栈顺序，35 是次顶元素， 6 是栈顶栈顶元素
	 * @param list
	 * @return
	 */
	public static int cal(List<String> list) {
		
		//创建一个栈
		Stack<String> stack = new Stack<>();
		
		//遍历list
		for(String item : list) {
			//正则匹配 多个数字 d = [0-9] ; + 代表多个
			if(item.matches("\\d+")) {
				//入栈
				stack.push(item);
				
			}else {
				//运算符直接有运算
				int num1 = Integer.parseInt(stack.pop());
				int num2 = Integer.parseInt(stack.pop());
				int res = 0;
				
				//后缀表达式也是从左向右运算，只剩 运算符 在 数字 后面，所以左侧数字先入栈
				//右侧数字后入栈，用 num2 - num1
				if(item.equals("+")) {
					res = num1 + num2;
				}else if(item.equals("-")) {
					res = num2 - num1;
				}else if(item.equals("*")) {
					res = num1 * num2;
				}else if(item.equals("/")) {
					res = num2 / num1;
				}
				
				//结果入栈
				stack.push(res + "");
			}
			
			
		}
		//最后只剩结果
		return Integer.parseInt(stack.pop());
	}
}
